package cn.schoolwow.quickdao.module.database.dml.json.kit;

import cn.schoolwow.quickdao.domain.database.dml.CheckStrategy;
import cn.schoolwow.quickdao.domain.database.dml.CompareJSONArrayResult;
import cn.schoolwow.quickdao.module.database.dml.common.domain.ManipulationOption;
import cn.schoolwow.quickdao.module.database.dml.common.service.GetJSONArrayReasonMapCompositeBusiness;
import cn.schoolwow.quickdao.module.database.dml.json.service.compare.CompareJSONArrayFlow;
import cn.schoolwow.quickdao.module.database.dml.json.service.delete.DeleteJSONArrayFlow;
import cn.schoolwow.quickdao.module.database.dml.json.service.delete.DeleteJSONObjectCompositeBusiness;
import cn.schoolwow.quickdao.module.database.dml.json.service.insert.InsertIgnoreJSONArrayFlow;
import cn.schoolwow.quickdao.module.database.dml.json.service.insert.InsertIgnoreJSONObjectFlow;
import cn.schoolwow.quickdao.module.database.dml.json.service.insert.InsertJSONArrayCompositeBusiness;
import cn.schoolwow.quickdao.module.database.dml.json.service.insert.InsertJSONObjectCompositeBusiness;
import cn.schoolwow.quickdao.module.database.dml.json.service.save.SaveJSONArrayCompositeBusiness;
import cn.schoolwow.quickdao.module.database.dml.json.service.save.SaveJSONObjectFlow;
import cn.schoolwow.quickdao.module.database.dml.json.service.update.UpdateJSONArrayCompositeBusiness;
import cn.schoolwow.quickdao.module.database.dml.json.service.update.UpdateJSONObjectCompositeBusiness;
import cn.schoolwow.quickdao.module.database.parent.kit.DatabaseDAOImpl;
import cn.schoolwow.quickflow.QuickFlow;
import cn.schoolwow.quickflow.domain.FlowContext;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.Map;

public class DatabaseManipulationJSONImpl extends DatabaseDAOImpl implements DatabaseManipulationJSON {
    public DatabaseManipulationJSONImpl(QuickFlow quickFlow) {
        super(quickFlow);
    }

    @Override
    public Map<JSONObject, String> getReasonInstanceMap(String tableName, JSONArray instances) {
        if(null==instances||instances.size()==0){
            return null;
        }
        ManipulationOption manipulationOption = quickFlow.getContextThreadLocalInstanceData(ManipulationOption.class);
        manipulationOption.checkStrategy = CheckStrategy.CheckAndFilter;
        FlowContext flowContext = quickFlow.startFlow(new GetJSONArrayReasonMapCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("instances", instances)
                .putInstanceData(manipulationOption)
                .execute();
        if(manipulationOption.uniqueFieldNames.isEmpty()){
            throw new IllegalArgumentException("先调用uniqueFieldNames方法指定唯一字段");
        }
        Map<JSONObject,String> instanceReasonMap = (Map<JSONObject,String>) flowContext.getData("instanceReasonMap");
        return instanceReasonMap;
    }

    @Override
    public int insert(String tableName, JSONObject instance) {
        if(null==instance){
            return 0;
        }
        FlowContext flowContext = quickFlow.startFlow(new InsertJSONObjectCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("instance", instance)
                .execute();
        return getEffect(flowContext);
    }

    @Override
    public int insert(String tableName, JSONArray instances) {
        if(null==instances||instances.isEmpty()){
            return 0;
        }
        FlowContext flowContext = quickFlow.startFlow(new InsertJSONArrayCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("instances", instances)
                .execute();
        return getEffect(flowContext);
    }

    @Override
    public CompareJSONArrayResult compareJSONArray(String tableName, JSONArray currentJSONArray) {
        return compareJSONArray(tableName, currentJSONArray, null);
    }

    @Override
    public CompareJSONArrayResult compareJSONArray(String tableName, JSONArray currentJSONArray, JSONArray totalJSONArray) {
        if (null==currentJSONArray||currentJSONArray.isEmpty()) {
            return new CompareJSONArrayResult();
        }
        FlowContext flowContext = quickFlow.startFlow(new CompareJSONArrayFlow())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("currentJSONArray", currentJSONArray)
                .putTemporaryData("totalJSONArray", totalJSONArray)
                .execute();
        CompareJSONArrayResult compareJSONArrayResult = flowContext.checkInstanceData(CompareJSONArrayResult.class);
        return compareJSONArrayResult;
    }

    @Override
    public int insertIgnore(String tableName, JSONObject instance) {
        if(null==instance){
            return 0;
        }
        FlowContext flowContext = quickFlow.startFlow(new InsertIgnoreJSONObjectFlow())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("instance", instance)
                .execute();
        return getEffect(flowContext);
    }

    @Override
    public int insertIgnore(String tableName, JSONArray instances) {
        if(null==instances||instances.isEmpty()){
            return 0;
        }
        FlowContext flowContext = quickFlow.startFlow(new InsertIgnoreJSONArrayFlow())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("instances", instances)
                .execute();
        return getEffect(flowContext);
    }

    @Override
    public int update(String tableName, JSONObject instance) {
        if(null==instance){
            return 0;
        }
        FlowContext flowContext = quickFlow.startFlow(new UpdateJSONObjectCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("instance", instance)
                .execute();
        return getEffect(flowContext);
    }

    @Override
    public int update(String tableName, JSONArray instances) {
        if(null==instances||instances.isEmpty()){
            return 0;
        }
        FlowContext flowContext = quickFlow.startFlow(new UpdateJSONArrayCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("instances", instances)
                .execute();
        return getEffect(flowContext);
    }

    @Override
    public int save(String tableName, JSONObject instance) {
        if (null == instance) {
            return 0;
        }
        FlowContext flowContext = quickFlow.startFlow(new SaveJSONObjectFlow())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("instance", instance)
                .execute();
        return getEffect(flowContext);
    }

    @Override
    public int save(String tableName, JSONArray instances) {
        if (null == instances || instances.isEmpty()) {
            return 0;
        }
        FlowContext flowContext = quickFlow.startFlow(new SaveJSONArrayCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("instances", instances)
                .execute();
        return getEffect(flowContext);
    }

    @Override
    public int delete(String tableName, JSONObject instance) {
        if(null==instance){
            return 0;
        }
        FlowContext flowContext = quickFlow.startFlow(new DeleteJSONObjectCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("instance", instance)
                .execute();
        return getEffect(flowContext);
    }

    @Override
    public int delete(String tableName, JSONArray instances) {
        if(null==instances||instances.isEmpty()){
            return 0;
        }
        FlowContext flowContext = quickFlow.startFlow(new DeleteJSONArrayFlow())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("instances", instances)
                .execute();
        return getEffect(flowContext);
    }

}
